const {
    db,
    sqlExec,
    sqlExecInTransaction,
    startTransaction,
    commitTransaction,
    rollbackTransaction
} = require('../db/mysql57');
const minio = require('../db/minio');

const config = require('../config');

const circlePostDao = {
    /*
     * 上传动态图片
     */
    async uploadCirclePostImg(uid, buffer, circlePostId, idx) {
        // 尝试开启事务
        let connection;
        let result;
        let browser = config.minio.postBrower;
        let uri = '';
        try {
            connection = await startTransaction();
        } catch (error) {
            return { success: false, msg: '数据库连接失败' };
        }
        // 往 PublicImg 表中插入数据
        try {
            let status = '待上传';
            let sql = `insert into CirclePostImg (uid, circlePostId, idx, browser, uri, status) VALUES (?, ?, ?, ?, ?, ?)`;
            let data = [uid, circlePostId, idx, browser, uri, status];
            result = await sqlExecInTransaction(connection, sql, data);
        } catch (error) {
            await rollbackTransaction(connection);
            return { success: false, msg: '数据库连接失败' };
        }
        // 往 MinIO 中上传图片（这个操作应该要封装到 minio 驱动里，后续修改）
        try {
            uri = `${result.insertId}.jpg`;
            await new Promise((resolve, reject) => {
                minio.minio.putObject(browser, uri, buffer, buffer.length, async function (err, etag) {
                    if (err) {
                        reject(err);
                        return ;
                    }
                });
                resolve(true);
            });
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '上传对象存储服务失败' };
        }
        // 更新 mysql 数据库中 图片的上传状态
        try {
            let sql = `update CirclePostImg set status = ?, uri = ? where id = ?`;
            let data = ['已完成未发布', uri, result.insertId];
            await sqlExecInTransaction(connection, sql, data);
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '操作数据库失败' };
        }
        // 提交事务
        try {
            commitTransaction(connection);
        } catch (error) {
            await rollbackTransaction(connection);
            return { success: false, msg: '事务提交失败' };
        }
        // 返回数据
        return { success: true, msg: "上传图片成功", data: result.insertId };
    },
    /*
     * 预发布动态接口
     */
    async preAddCirclePost(uid, title, publishTime, content, circlePostTypeId) {
        let sql = `insert into CirclePost (
                uid, title, publishTime, content, circlePostTypeId
            ) values (?, ?, ?, ?, ?)`;
        let data = [uid, title, publishTime, content, circlePostTypeId];
        return sqlExec(sql, data);
    },
    /*
     * 发布动态
     */
    async addCirclePost(uid, circlePostId) {
        // 尝试开启事务
        let connection;
        let result;
        let imgIdList = [];
        try {
            connection = await startTransaction();
        } catch (error) {
            return { success: false, msg: '数据库连接失败' };
        }
        try {
            let sql = `select * from CirclePost where id = ? and uid = ?`;
            let data = [circlePostId, uid];
            let res = await sqlExecInTransaction(connection, sql, data);
            if (res.length == 0) {
                return { success: false, msg: '动态不存在' };
            }
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '数据库连接失败' };
        }
        try {
            let sql = `select id, idx from CirclePostImg where circlePostId = ? order by idx asc`;
            let data = [ circlePostId ];
            let res = await sqlExecInTransaction(connection, sql, data);
            imgIdList = res.map(item => item.id);
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '数据库连接失败' };
        }
        try {
            let sql = `update CirclePostImg set status = ? where id = ?`;
            for (let i = 0; i < imgIdList.length; i++) {
                let data = [ '已发布', imgIdList[i] ];
                let res = await sqlExecInTransaction(connection, sql, data);
            }
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '数据库连接失败' };
        }
        try {
            let sql = `update CirclePost set imgIdList = ?, status = ? where id = ?`;
            let data = [ JSON.stringify(imgIdList), '已发布', circlePostId ];
            let res = await sqlExecInTransaction(connection, sql, data);
            if (res.affectedRows == 1) {
                result = { success: true, msg: '发布成功' };
            } else {
                result = { success: false, msg: '发布失败' };
            }
        } catch (err) {
            await rollbackTransaction(connection);
            return { success: false, msg: '数据库连接失败' };
        }
        // 提交事务
        try {
            commitTransaction(connection);
        } catch (error) {
            await rollbackTransaction(connection);
            return { success: false, msg: '事务提交失败' };
        }
        // 返回数据
        return result;
    },
    /*
     * 查看动态详情
     */
    async getPostInfo(uid, postId) {
        let sql = `select
            cp.id as id,
            cp.uid as uid,
            u.username as username,
            u.userIcon as userIcon,
            cp.title as title,
            DATE_FORMAT(cp.publishTime, '%Y-%m-%d %H:%i:%s') as publishTime,
            cp.content as content,
            cp.imgIdList as imgIdList,
            cpt.name as circlePostType,
            cpt.textColor as circlePostTypeTextColor,
            cpt.bgColor as circlePostTypeBgColor,
            (select count(*) from PostLike where PostLike.circlePostId = cp.id) as likeCount,
            (select count(*) from PostComment where PostComment.circlePostId = cp.id) as commentCount,
            (select count(*) from PostLike where PostLike.circlePostId = cp.id and PostLike.uid = ?) as isLike
        from CirclePost as cp
        left join User as u on cp.uid = u.id
        left join CirclePostType as cpt on cp.circlePostTypeId = cpt.id
        where cp.id = ?
        Limit 1`;
        let data = [uid, postId];
        return sqlExec(sql, data);
    },
    /*
     * 删除动态
     */
    async delPost(uid, postId) {
        let sql = `delete from CirclePost
            where uid = ? and id = ?`;
        let data = [uid, postId];
        return sqlExec(sql, data);
    },
    /*
     * 点赞动态
     */
    async likePost(uid, postId) {
        let sql = `insert into PostLike (
                uid, circlePostId
            ) (select ?, ? where not exists (select * from PostLike where uid = ? and circlePostId = ?))`;
        let data = [ uid, postId, uid, postId ];
        return sqlExec(sql, data);
    },
    /*
     * 取消点赞动态
     */
    async nolikePost(uid, postId) {
        let sql = `delete from PostLike
            where uid = ? and circlePostId = ?`;
        let data = [uid, postId];
        return sqlExec(sql, data);
    },
    /*
     * 评论动态
     */
    async addCommentPost(uid, postId, time, content) {
        let sql = `insert into PostComment (
                uid, circlePostId, time, content
            ) VALUES (?, ?, ?, ?)`;
        let data = [uid, postId, time, content];
        return sqlExec(sql, data);
    },
    /*
     * 删除评论
     */
    async delCommentPost(uid, postCommentId) {
        let sql = `delete from PostComment
            where uid = ? and id = ?`;
        let data = [uid, postCommentId];
        return sqlExec(sql, data);
    },
    /*
     * 获取推荐动态列表
     */
    async getRecommendPostList(uid, lastPostId) {
        let sql;
        let data;
        if (lastPostId) {
            sql = `select
                cp.id as id,
                u.username as username,
                u.userIcon as userIcon,
                cp.title as title,
                DATE_FORMAT(cp.publishTime, '%Y-%m-%d %H:%i:%s') as publishTime,
                cp.content as content,
                cp.imgIdList as imgIdList,
                cpt.name as circlePostType,
                cpt.textColor as circlePostTypeTextColor,
                cpt.bgColor as circlePostTypeBgColor,
                (select count(*) from PostLike where PostLike.circlePostId = cp.id) as likeCount,
                (select count(*) from PostComment where PostComment.circlePostId = cp.id) as commentCount,
                (select count(*) from PostLike where PostLike.circlePostId = cp.id and PostLike.uid = ?) as isLike
            from CirclePost as cp
            left join User as u on cp.uid = u.id
            left join CirclePostType as cpt on cp.circlePostTypeId = cpt.id
            where cp.publishTime < (
                select publishTime from CirclePost where id = ?
            ) and cp.status = '已发布'
            ORDER BY cp.publishTime DESC
            LIMIT 20`;
            data = [uid, lastPostId];
        } else {
            sql = `select
                cp.id as id,
                u.username as username,
                u.userIcon as userIcon,
                cp.title as title,
                DATE_FORMAT(cp.publishTime, '%Y-%m-%d %H:%i:%s') as publishTime,
                cp.content as content,
                cp.imgIdList as imgIdList,
                cpt.name as circlePostType,
                cpt.textColor as circlePostTypeTextColor,
                cpt.bgColor as circlePostTypeBgColor,
                (select count(*) from PostLike where PostLike.circlePostId = cp.id) as likeCount,
                (select count(*) from PostComment where PostComment.circlePostId = cp.id) as commentCount,
                (select count(*) from PostLike where PostLike.circlePostId = cp.id and PostLike.uid = ?) as isLike
            from CirclePost as cp
            left join User as u on cp.uid = u.id
            left join CirclePostType as cpt on cp.circlePostTypeId = cpt.id
            where cp.status = '已发布'
            ORDER BY cp.publishTime DESC
            LIMIT 20`;
            data = [uid];
        }
        return sqlExec(sql, data);
    },
    /*
     * 获取评论列表
     */
    async getPostCommentList(postId, lastPostCommentId) {
        let sql;
        let data;
        if (lastPostCommentId) {
            sql = `select
                    u.username as username,
                    u.userIcon as userIcon,
                    DATE_FORMAT(pc.time, '%Y-%m-%d %H:%i:%s') as time,
                    pc.content as content,
                    pc.id as id
                from PostComment as pc
                left join User as u on pc.uid = u.id
                where pc.circlePostId = ? and pc.time < (
                    select time from PostComment where id = ?
                )
                ORDER BY pc.time DESC
                LIMIT 20`;
            data = [postId, lastPostCommentId];
        } else {
            sql = `select
                    u.username as username,
                    u.userIcon as userIcon,
                    DATE_FORMAT(pc.time, '%Y-%m-%d %H:%i:%s') as time,
                    pc.content as content,
                    pc.id as id
                from PostComment as pc
                left join User as u on pc.uid = u.id
                where pc.circlePostId = ?
                ORDER BY pc.time DESC
                LIMIT 20`;
            data = [postId];
        }
        return sqlExec(sql, data);
    },
    async getCirclePostImgUrl(imgId) {
        let sql = `select browser, uri from CirclePostImg where id = ? and status = ?`;
        let data = [ imgId, '已发布' ];
        let result = await sqlExec(sql, data);
        if (result.length === 0) {
            return { success: false, msg: '文件不存在' };
        }
        let { browser, uri } = result[0];
        return minio.getDownloadUrl(browser, uri, 36000);
    },
    async getAllCirclePostType() {
        let sql = `select id, name text from CirclePostType`;
        let data = [];
        return sqlExec(sql, data);
    }
};

module.exports = circlePostDao;
